// cmd/server/main.go
package main

import (
	"log"
	"strconv"
	"time"

	"github.com/gin-gonic/gin"

	"github.com/jfastfiler/internal/config"
	"github.com/jfastfiler/internal/dao"
	"github.com/jfastfiler/internal/service"
	"github.com/jfastfiler/internal/api"
	"github.com/jfastfiler/internal/middleware"
	"github.com/jfastfiler/pkg/security"
	"github.com/jfastfiler/pkg/storage"
)

func main() {
	// 加载配置
	cfg, err := config.LoadConfig("config.yaml")
	if err != nil {
		log.Fatal("加载配置失败:", err)
	}

	// 初始化数据库
	database, err := dao.NewDatabase(cfg.Database.Path, cfg.Database.MaxConn, 
		cfg.Database.IdleConn, time.Duration(cfg.Database.ConnLifetime)*time.Second)
	if err != nil {
		log.Fatal("数据库初始化失败:", err)
	}
	defer database.Close()

	// 初始化数据库表和数据
	err = database.InitData()
	if err != nil {
		log.Fatal("数据库初始化数据失败:", err)
	}

	// 初始化DAO
	userDAO := dao.NewUserDAO(database)
	fileDAO := dao.NewFileMetadataDAO(database)
	permDAO := dao.NewPermissionDAO(database)
	auditDAO := dao.NewAuditDAO(database)
	searchDAO := dao.NewSearchDAO(database)

	// 初始化存储
	var fileStorage storage.Storage
	if cfg.Storage.Type == "local" {
		fileStorage = storage.NewLocalStorage(cfg.Storage.Local.Path)
	} else {
		// 可以扩展支持其他存储类型，如S3、OSS等
		fileStorage = storage.NewLocalStorage(cfg.Storage.Local.Path)
	}

	// 初始化安全组件
	virusScanner := security.NewVirusScanner(cfg.Security.VirusScan.Enabled, 
		cfg.Security.VirusScan.ClamavHost, cfg.Security.VirusScan.ClamavPort)
		
	watermark := security.NewWatermark(cfg.Security.Watermark.Enabled, 
		cfg.Security.Watermark.Text, cfg.Security.Watermark.Opacity, 
		cfg.Security.Watermark.FontSize)

	// 初始化服务
	authService := service.NewAuthService(userDAO, auditDAO, cfg.Security.JWTSecret, 
		time.Duration(cfg.Security.TokenExpire)*time.Second, cfg.Security.BcryptCost)
		
	fileService := service.NewFileService(fileDAO, permDAO, auditDAO, fileStorage, 
		virusScanner, cfg.Storage.Local.Path, cfg.Storage.TempPath, 
		cfg.Storage.MaxFileSize, cfg.Security.EnableEncryption)
		
	userService := service.NewUserService(userDAO, auditDAO)
	searchService := service.NewSearchService(searchDAO, fileDAO)
	previewService := service.NewPreviewService(fileDAO, cfg.Preview.BasePath, 
		cfg.Storage.TempPath, cfg.Storage.Local.Path, cfg.Preview.MaxWorkers, 
		cfg.Preview.ImageQuality, cfg.Preview.DocumentTimeout, cfg.Preview.LibreofficePath)

	// 初始化控制器
	authController := api.NewAuthController(authService)
	fileController := api.NewFileController(fileService)
	userController := api.NewUserController(userService)
	searchController := api.NewSearchController(searchService)
	previewController := api.NewPreviewController(previewService)

	// 设置Gin模式
	gin.SetMode(cfg.Server.Mode)
	router := gin.Default()

	// 全局中间件
	router.Use(gin.Recovery())
	router.Use(middleware.SecurityMiddleware())
	router.Use(middleware.RateLimitMiddleware())
	router.Use(middleware.AuditMiddleware(auditDAO))

	// 静态文件服务
	router.Static("/storage", cfg.Storage.Local.Path)
	router.Static("/previews", cfg.Preview.BasePath)
	router.Static("/web", "./web")

	// API路由分组
	apiGroup := router.Group("/api/v1")
	{
		// 认证路由
		authGroup := apiGroup.Group("/auth")
		{
			authGroup.POST("/login", authController.Login)
			authGroup.POST("/refresh", authController.RefreshToken)
			authGroup.POST("/change-password", authController.ChangePassword)
		}

		// 需要认证的路由
		authorized := apiGroup.Group("")
		authorized.Use(middleware.AuthMiddleware(authService))
		{
			// 文件管理路由
			filesGroup := authorized.Group("/files")
			{
				filesGroup.GET("", fileController.ListFiles)
				filesGroup.POST("/upload", fileController.UploadFile)
				filesGroup.POST("/mkdir", fileController.CreateDirectory)
				filesGroup.POST("/batch", fileController.BatchOperation)
				filesGroup.GET("/download/:id", fileController.DownloadFile)
				filesGroup.GET("/:id", fileController.GetFileInfo)
			}

			// 搜索路由
			searchGroup := authorized.Group("/search")
			{
				searchGroup.GET("", searchController.Search)
				searchGroup.POST("/advanced", searchController.AdvancedSearch)
				searchGroup.GET("/history", searchController.GetSearchHistory)
			}

			// 预览路由
			previewGroup := authorized.Group("/preview")
			{
				previewGroup.POST("", previewController.GeneratePreview)
				previewGroup.GET("/status/:file_id", previewController.GetPreviewStatus)
				previewGroup.GET("/text/:file_id", previewController.ExtractText)
			}

			// 用户管理路由（需要管理员权限）
			usersGroup := authorized.Group("/users")
			usersGroup.Use(middleware.RBACMiddleware("admin"))
			{
				usersGroup.POST("", userController.CreateUser)
				usersGroup.GET("", userController.ListUsers)
				usersGroup.PUT("/:id", userController.UpdateUser)
				usersGroup.DELETE("/:id", userController.DeleteUser)
				usersGroup.POST("/:id/reset-password", userController.ResetPassword)
			}

			// 个人资料路由
			profileGroup := authorized.Group("/profile")
			{
				profileGroup.GET("/:id", userController.GetUserProfile)
				profileGroup.PUT("/:id", userController.UpdateUserProfile)
			}
		}

		// 管理接口（需要管理员权限）
		adminGroup := apiGroup.Group("/admin")
		adminGroup.Use(middleware.AuthMiddleware(authService))
		adminGroup.Use(middleware.RBACMiddleware("admin"))
		{
			adminGroup.GET("/stats", api.GetSystemStats)
			adminGroup.GET("/logs", api.GetAuditLogs)
			adminGroup.POST("/cleanup", api.CleanupSystem)
		}
	}

	// 健康检查端点
	router.GET("/health", func(ctx *gin.Context) {
		ctx.JSON(200, gin.H{"status": "ok", "timestamp": time.Now()})
	})

	// API文档路由
	router.GET("/", func(ctx *gin.Context) {
		ctx.Redirect(302, "/web/index.html")
	})

	// 启动服务器
	addr := cfg.Server.Host + ":" + strconv.Itoa(cfg.Server.Port)
	log.Printf("JFastFiler 服务启动在 %s (模式: %s)", addr, cfg.Server.Mode)
	
	if err := router.Run(addr); err != nil {
		log.Fatal("服务器启动失败:", err)
	}
}